package org.raghu.sql.query.builder;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * 
 * SQL query builder class
 * 
 * @author Raghunathan K Semburakkiannan
 * 
 */
public class SqlQueryBuilder {
	private final Logger logger = LoggerFactory.getLogger(SqlQueryBuilder.class);
	
	private StringBuffer queryString = new StringBuffer();
	
	public SqlQueryBuilder insert(String tableName, String... columns) {
		StringBuffer sb = new StringBuffer("INSERT INTO ");
		sb.append(tableName);
		sb.append(columns.length>0 ? "(":"");
		
		for(String column: columns) {
			sb.append(column).append(", ");
		}
		
		if (columns.length>0) {
			sb.deleteCharAt(sb.length() - 2);
			sb.append(")");
			sb.append(" VALUES (");
			for(int i=1; i<=columns.length; i++){
				sb.append("?, ");
			}
			sb.deleteCharAt(sb.length() - 2);
			sb.append(")");
		}
		
		queryString.append(sb);
		return this;
	}
	
	public SqlQueryBuilder update(String tableName, String... columns){
		StringBuffer sb = new StringBuffer("UPDATE ");
		sb.append(tableName).append(" SET ");
		for(String column: columns) {
			sb.append(column).append(" = ?, ");
		}
		sb.deleteCharAt(sb.length() - 2);
		queryString.append(sb);
		return this;
	}
	
	public SqlQueryBuilder delete() {
		StringBuffer sb = new StringBuffer("DELETE");
		
		queryString.append(sb);
		return this;
	}

	public SqlQueryBuilder select(String... columns) {
		StringBuffer sb = new StringBuffer("SELECT ");
		for (String columnName : columns) {
			sb.append(columnName).append(", ");
		}
		sb.deleteCharAt(sb.length() - 2);
		queryString.append(sb);
		return this;
	}

	public SqlQueryBuilder selectFrom(String tableName) {
		StringBuffer sb = new StringBuffer("SELECT * FROM ");
		sb.append(tableName);
		queryString.append(sb);
		return this;
	}

	public SqlQueryBuilder from(String tableName) {
		StringBuffer sb = new StringBuffer();
		sb.append(" FROM ").append(tableName);

		queryString.append(sb);
		return this;
	}

	public SqlQueryBuilder where(String firstOperand, LogicalOperator logicalOpr, String secondOperand) {
		construct(firstOperand, logicalOpr, secondOperand, " WHERE ");
		return this;
	}
	
	public SqlQueryBuilder where() {
		queryString.append(" WHERE ");
		return this;
	}
	
	public SqlQueryBuilder and() {
		queryString.append(" AND ");
		return this;
	}
	
	public SqlQueryBuilder or() {
		queryString.append(" OR ");
		return this;
	}
	
	public SqlQueryBuilder and(String firstOperand, LogicalOperator logicalOpr, String secondOperand){
		construct(firstOperand, logicalOpr, secondOperand, " AND ");
		return this;
	}
	
	public SqlQueryBuilder or(String firstOperand, LogicalOperator logicalOpr, String secondOperand){
		construct(firstOperand, logicalOpr, secondOperand, " OR ");
		return this;
	}
	
	private void construct(String firstOperand, LogicalOperator logicalOpr, String secondOperand, String keyWord) {
		StringBuffer sb = new StringBuffer(keyWord);
		sb.append("(").append(firstOperand).append(logicalOpr).append(secondOperand).append(")");
		queryString.append(sb);
	}
	
	public SqlQueryBuilder like(String columnName, String pattern) {
		StringBuffer sb = new StringBuffer();
		sb.append("(").append(columnName).append(" LIKE '").append(pattern).append("')");
		queryString.append(sb);
		return this;
	}
	
	public String toSql() {
		return toString();
	}

	public String toString() {
		logger.info("Generated SQL:{}", queryString.toString());
		return queryString.toString();
	}
	
	public static void main(String[] args) {
		System.out.println(new SqlQueryBuilder().selectFrom("Emp").where("emp", LogicalOperator.GT, "10").and("age", LogicalOperator.LE, "?"));
		
	}


}
